package ar.com.fiuba.ElectronicCircuitAnalyst.infrastructure.db4o.repository;

import java.util.ArrayList;
import java.util.List;

import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.Circuit;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.repository.CircuitRepository;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.exceptions.CircuitElementNotFoundException;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.exceptions.ElementNotFoundException;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.impl.CircuitImpl;
import ar.com.fiuba.ElectronicCircuitAnalyst.infrastructure.db4o.repository.predicate.RelatedCircuitsPredicate;

import com.db4o.ObjectSet;

public class CircuitRepositoryImpl extends RepositoryImpl<Circuit> implements CircuitRepository {

	public CircuitRepositoryImpl() {
		super(Circuit.class);
	}

	public Circuit getCircuitByName(String name) throws CircuitElementNotFoundException {
		return getCircuit(name);
	}

	public void removeCircuitByName(String name) throws CircuitElementNotFoundException {
		try {
			remove(getCircuit(name));
		} catch (ElementNotFoundException e) {
			throw new CircuitElementNotFoundException("Circuit with the name \"" + name + "\" was not found.");
		}
	}

	public List<Circuit> getRelatedCircuits(String name) {

		List<Circuit> temp = this.getDb().query(new RelatedCircuitsPredicate(name));

		List<Circuit> allCircuits = new ArrayList<Circuit>();
		allCircuits.addAll(temp);

		List<Circuit> aux = new ArrayList<Circuit>();
		aux.addAll(allCircuits);

		for (Circuit circuit : aux) {
			List<Circuit> moreCircuits = getRelatedCircuits(circuit.getName());
			if (!moreCircuits.isEmpty())
				allCircuits.addAll(moreCircuits);
		}

		return allCircuits;
	}

	private Circuit getCircuit(String name) throws CircuitElementNotFoundException {

		ObjectSet<Circuit> circuits = getDb().queryByExample(CircuitImpl.getEmptyCircuit(name));

		if (circuits.size() == 0) {
			throw new CircuitElementNotFoundException("Circuit with name " + name + " not found");
		}

		return circuits.get(0);

	}

}
